package com.cinc.ebc.mm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cinc.ebc.mm.entity.*;
import com.cinc.ebc.mm.mapper.MmStockInitDetailMapper;
import com.cinc.ebc.mm.mapper.MmStockInitMapper;
import com.cinc.ebc.mm.model.MmStockInitDetailModel;
import com.cinc.ebc.mm.service.IMmStockInOutService;
import com.cinc.ebc.mm.service.IMmStockInitService;
import com.cinc.ebc.mm.vo.MmStockInitDetailPage;
import com.cinc.mdm.modules.codeRule.service.IMdmCodeRuleService;
import com.cinc.mdm.modules.movementType.service.IMdmMovementTypeService;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 库存初始化
 * @Author: jeecg-boot
 * @Date: 2022-07-03
 * @Version: V1.0
 */
@Service
public class MmStockInitServiceImpl extends ServiceImpl<MmStockInitMapper, MmStockInit> implements IMmStockInitService {

    @Autowired
    private MmStockInitMapper mmStockInitMapper;
    @Autowired
    private MmStockInitDetailMapper mmStockInitDetailMapper;
    @Autowired
    private IMdmMovementTypeService mdmMovementTypeService;
    @Autowired
    private IMmStockInOutService mmStockInOutService;
    @Autowired
    private IMdmCodeRuleService mdmCodeRuleService;

    @Override
    @Transactional
    public void saveMain(MmStockInit mmStockInit, List<MmStockInitDetail> mmStockInitDetailList) {
        String moveId = mdmMovementTypeService.findIdByTypeNo("561");
        mmStockInit.setMoveId(moveId);
        mmStockInitMapper.insert(mmStockInit);
        if (mmStockInitDetailList != null && mmStockInitDetailList.size() > 0) {
            for (MmStockInitDetail entity : mmStockInitDetailList) {
                //外键设置
                entity.setPid(mmStockInit.getId());
                entity.setWarehouseId(mmStockInit.getWarehouseId());
                mmStockInitDetailMapper.insert(entity);
            }
        }
    }

    @Override
    @Transactional
    public void updateMain(MmStockInit mmStockInit, List<MmStockInitDetail> mmStockInitDetailList) {
        mmStockInitMapper.updateById(mmStockInit);

        //1.先删除子表数据
        mmStockInitDetailMapper.deleteByMainId(mmStockInit.getId());

        //2.子表数据重新插入
        if (mmStockInitDetailList != null && mmStockInitDetailList.size() > 0) {
            for (MmStockInitDetail entity : mmStockInitDetailList) {
                //外键设置
                entity.setPid(mmStockInit.getId());
                mmStockInitDetailMapper.insert(entity);
            }
        }
    }

    @Override
    @Transactional
    public void delMain(String id) {
        mmStockInitDetailMapper.deleteByMainId(id);
        mmStockInitMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void delBatchMain(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            mmStockInitDetailMapper.deleteByMainId(id.toString());
            mmStockInitMapper.deleteById(id);
        }
    }

    @Override
    public void detaiPage(Page<MmStockInitDetailModel> page, MmStockInitDetailPage detailPage) {
        String sql = QueryGenerator.installAuthJdbc(MmStockInit.class);
        page.setRecords(mmStockInitDetailMapper.selectDetailList(page, detailPage,sql));
    }

    @Override
    public List<MmStockInitDetailModel> detailList(MmStockInitDetailPage detailPage) {
        String sql = QueryGenerator.installAuthJdbc(MmStockInit.class);
        return mmStockInitDetailMapper.selectDetailList(null, detailPage,sql);
    }

    @Transactional
    @Override
    public void handleInit(List<MmStockInitDetailPage> detailPageList) throws Exception {
        List<String> allIdList = detailPageList.stream().map(MmStockInitDetailPage::getId).collect(Collectors.toList());
        QueryWrapper<MmStockInitDetail> detailQuery = new QueryWrapper<>();
        detailQuery.in("id", allIdList);
        detailQuery.eq("init_flag", "1");
        int initCount = mmStockInitDetailMapper.selectCount(detailQuery);
        if (initCount > 0) {
            throw new RuntimeException("已经初始化的单据不能再次操作");
        }
        Map<String, List<MmStockInitDetailPage>> pidAndDataMap = detailPageList.stream().collect(Collectors.groupingBy(MmStockInitDetailPage::getPid));
        for (String pid : pidAndDataMap.keySet()) {
            List<MmStockInitDetailPage> stockInitDetailPageList = pidAndDataMap.get(pid);
            String billNo = stockInitDetailPageList.get(0).getBillNo();
            String warehouseId = stockInitDetailPageList.get(0).getWarehouseId();
            String supplyId = stockInitDetailPageList.get(0).getSupplyId();
            String moveId = stockInitDetailPageList.get(0).getMoveId();
            //更新初始化标志
            MmStockInitDetail stockInitDetailModify = new MmStockInitDetail();
            stockInitDetailModify.setInitFlag("1");
            List<String> idList = stockInitDetailPageList.stream().map(MmStockInitDetailPage::getId).collect(Collectors.toList());
            mmStockInitDetailMapper.update(stockInitDetailModify, new QueryWrapper<MmStockInitDetail>().in("id", idList));
            //生成入库单
            MmStockInOut mmStockInOut = new MmStockInOut();
            mmStockInOut.setIoFlag("i");
            mmStockInOut.setMoveId(moveId);
            mmStockInOut.setWarehouseId(warehouseId);
            mmStockInOut.setSupplyId(supplyId);
            int lineNo = 10;
            List<MmStockInOutDetail> mmStockInOutDetailList = new ArrayList<>();
            for (MmStockInitDetailPage stockInitDetailPage : stockInitDetailPageList) {
                MmStockInOutDetail mmStockInOutDetail = new MmStockInOutDetail();
                mmStockInOutDetail.setLineNo(lineNo++);
                mmStockInOutDetail.setMaterialId(stockInitDetailPage.getMaterialId());
                mmStockInOutDetail.setMaterialNo(stockInitDetailPage.getMaterialNo());
                mmStockInOutDetail.setMaterialDesc(stockInitDetailPage.getMaterialDesc());
                mmStockInOutDetail.setUnit(stockInitDetailPage.getUnit());
                mmStockInOutDetail.setQty(stockInitDetailPage.getQty());
                mmStockInOutDetail.setUnitPrice(stockInitDetailPage.getUnitPrice());
                mmStockInOutDetail.setSumPrice(stockInitDetailPage.getSumPrice());
                mmStockInOutDetail.setSourceId(stockInitDetailPage.getId());
                mmStockInOutDetail.setSourceNo(billNo);
                mmStockInOutDetail.setBatchNo(stockInitDetailPage.getBatchNo());
                mmStockInOutDetail.setWarehouseId(warehouseId);
                mmStockInOutDetail.setStorageLocationId(stockInitDetailPage.getStorageLocationId());
                mmStockInOutDetailList.add(mmStockInOutDetail);
            }
            mmStockInOutService.saveMain(mmStockInOut, mmStockInOutDetailList,false);
        }
    }

    @Transactional
    @Override
    public void writeOff(List<MmStockInitDetailPage> detailPageList) throws Exception {
        List<String> allIdList = detailPageList.stream().map(MmStockInitDetailPage::getId).collect(Collectors.toList());
        QueryWrapper<MmStockInitDetail> detailQuery = new QueryWrapper<>();
        detailQuery.in("id", allIdList);
        detailQuery.eq("init_flag", "1");
        detailQuery.eq("handle_flag", "0");
        int initCount = mmStockInitDetailMapper.selectCount(detailQuery);
        if (initCount != detailPageList.size()) {
            throw new RuntimeException("只有已初始化未冲销的单据才能冲销!");
        }
        String reverseMoveId = mdmMovementTypeService.findReverseIdByTypeNo("561");
        if (oConvertUtils.isEmpty(reverseMoveId)) {
            throw new RuntimeException("未找到反向移动类型!");
        }
        Map<String, List<MmStockInitDetailPage>> pidAndDataMap = detailPageList.stream().collect(Collectors.groupingBy(MmStockInitDetailPage::getPid));
        for (String pid : pidAndDataMap.keySet()) {
            List<MmStockInitDetailPage> mmStockInitDetailPageList = pidAndDataMap.get(pid);
            String billNo = mmStockInitDetailPageList.get(0).getBillNo();
            String warehouseId = mmStockInitDetailPageList.get(0).getWarehouseId();
            String supplyId = mmStockInitDetailPageList.get(0).getSupplyId();
            List<String> idList = mmStockInitDetailPageList.stream().map(MmStockInitDetailPage::getId).collect(Collectors.toList());
            //更新原单据冲销标志
            MmStockInitDetail mmStockInitDetailModify = new MmStockInitDetail();
            mmStockInitDetailModify.setHandleFlag("1");
            mmStockInitDetailMapper.update(mmStockInitDetailModify, new QueryWrapper<MmStockInitDetail>().in("id", idList));
            //生成冲销单据
            MmStockInit mmStockInit = new MmStockInit();
            mmStockInit.setBillDate(new Date());
            mmStockInit.setBillNo(mdmCodeRuleService.generateStockInitCode());
            mmStockInit.setCancelBillNo(billNo);
            mmStockInit.setWarehouseId(warehouseId);
            mmStockInit.setSupplyId(supplyId);
            mmStockInit.setMoveId(reverseMoveId);
            List<MmStockInitDetail> stockInitDetailList = new ArrayList<>();
            int lineNo = 10;
            for (MmStockInitDetailPage stockInitDetailPage : mmStockInitDetailPageList) {
                MmStockInitDetail mmStockInitDetail = new MmStockInitDetail();
                mmStockInitDetail.setLineNo(lineNo++);
                mmStockInitDetail.setMaterialId(stockInitDetailPage.getMaterialId());
                mmStockInitDetail.setMaterialNo(stockInitDetailPage.getMaterialNo());
                mmStockInitDetail.setMaterialDesc(stockInitDetailPage.getMaterialDesc());
                mmStockInitDetail.setUnit(stockInitDetailPage.getUnit());
                mmStockInitDetail.setQty(stockInitDetailPage.getQty().negate());
                mmStockInitDetail.setUnitPrice(stockInitDetailPage.getUnitPrice());
                mmStockInitDetail.setSumPrice(stockInitDetailPage.getSumPrice().negate());
                mmStockInitDetail.setWarehouseId(warehouseId);
                mmStockInitDetail.setStorageLocationId(stockInitDetailPage.getStorageLocationId());
                mmStockInitDetail.setBatchNo(stockInitDetailPage.getBatchNo());
                mmStockInitDetail.setCancelDetailId(stockInitDetailPage.getId());
                mmStockInitDetail.setHandleFlag("1");
                mmStockInitDetail.setInitFlag("1");
                stockInitDetailList.add(mmStockInitDetail);
            }
            this.saveMain(mmStockInit, stockInitDetailList);
            //生成入库单
            MmStockInOut mmStockInOut = new MmStockInOut();
            mmStockInOut.setIoFlag("i");
            mmStockInOut.setMoveId(reverseMoveId);
            mmStockInOut.setWarehouseId(warehouseId);
            mmStockInOut.setSupplyId(supplyId);
            lineNo = 10;
            List<MmStockInOutDetail> mmStockInOutDetailList = new ArrayList<>();
            for (MmStockInitDetail stockInitDetail : stockInitDetailList) {
                MmStockInOutDetail mmStockInOutDetail = new MmStockInOutDetail();
                mmStockInOutDetail.setLineNo(lineNo++);
                mmStockInOutDetail.setMaterialId(stockInitDetail.getMaterialId());
                mmStockInOutDetail.setMaterialNo(stockInitDetail.getMaterialNo());
                mmStockInOutDetail.setMaterialDesc(stockInitDetail.getMaterialDesc());
                mmStockInOutDetail.setUnit(stockInitDetail.getUnit());
                mmStockInOutDetail.setQty(stockInitDetail.getQty());
                mmStockInOutDetail.setUnitPrice(stockInitDetail.getUnitPrice());
                mmStockInOutDetail.setSumPrice(stockInitDetail.getSumPrice());
                mmStockInOutDetail.setSourceId(stockInitDetail.getId());
                mmStockInOutDetail.setSourceNo(mmStockInit.getBillNo());
                mmStockInOutDetail.setBatchNo(stockInitDetail.getBatchNo());
                mmStockInOutDetail.setWarehouseId(stockInitDetail.getWarehouseId());
                mmStockInOutDetail.setStorageLocationId(stockInitDetail.getStorageLocationId());
                mmStockInOutDetail.setHandleFlag("1");
                //冲销明细ID 待处理
                mmStockInOutDetailList.add(mmStockInOutDetail);
            }
            mmStockInOutService.saveMain(mmStockInOut, mmStockInOutDetailList);
        }
    }

    @Override
    public void delDetail(String id) throws RuntimeException {
        MmStockInitDetail mmStockInitDetail = mmStockInitDetailMapper.selectById(id);
        if (mmStockInitDetail == null) {
            throw new RuntimeException("数据不存在!");
        }
        if ("1".equals(mmStockInitDetail.getInitFlag())) {
            throw new RuntimeException("已初始化单据不能删除!");
        }
        mmStockInitDetailMapper.deleteById(id);
    }

}
